/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.zimbra.common.calendar.ParsedDateTime;
/*     */ import com.zimbra.common.calendar.ParsedDuration;
/*     */ import com.zimbra.common.calendar.TimeZoneMap;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.mailbox.CalendarItem.Instance;
/*     */ import com.zimbra.cs.mailbox.calendar.RecurId;
/*     */ import com.zimbra.cs.mailbox.calendar.Recurrence.CancellationRule;
/*     */ import com.zimbra.cs.mailbox.calendar.Recurrence.ExceptionRule;
/*     */ import com.zimbra.cs.mailbox.calendar.Recurrence.IException;
/*     */ import com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence;
/*     */ import com.zimbra.cs.mailbox.calendar.Recurrence.RecurrenceRule;
/*     */ import com.zimbra.cs.mailbox.calendar.Util;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ExpandRecur
/*     */   extends MailDocumentHandler
/*     */ {
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  46 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  47 */     Account authAcct = getAuthenticatedAccount(zsc);
/*     */     
/*  49 */     long rangeStart = request.getAttributeLong("s");
/*  50 */     long rangeEnd = request.getAttributeLong("e");
/*  51 */     long days = (rangeEnd - rangeStart) / 86400000L;
/*  52 */     long maxDays = LC.calendar_freebusy_max_days.longValueWithinRange(0L, 36600L);
/*  53 */     if (days > maxDays) {
/*  54 */       throw ServiceException.INVALID_REQUEST("Requested range is too large (Maximum " + maxDays + " days)", null);
/*     */     }
/*  56 */     TimeZoneMap tzmap = new TimeZoneMap(Util.getAccountTimeZone(authAcct));
/*  57 */     ParsedRecurrence parsed = parseRecur(request, tzmap);
/*  58 */     List<CalendarItem.Instance> instances = getInstances(parsed, rangeStart, rangeEnd);
/*  59 */     Element response = getResponseElement(zsc);
/*  60 */     if (instances != null) {
/*  61 */       for (CalendarItem.Instance inst : instances) {
/*  62 */         addInstance(response, inst);
/*     */       }
/*     */     }
/*  65 */     return response;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   protected static ParsedRecurrence parseRecur(Element request, TimeZoneMap tzmap)
/*     */     throws ServiceException
/*     */   {
/*  74 */     CalendarUtils.parseTimeZones(request, tzmap);
/*  75 */     Recurrence.IRecurrence recurrence = null;
/*  76 */     List<Recurrence.IException> exceptions = new ArrayList();
/*  77 */     for (Iterator<Element> compIter = request.elementIterator(); compIter.hasNext();) {
/*  78 */       Element elem = (Element)compIter.next();
/*  79 */       String elemName = elem.getName();
/*  80 */       boolean isCancel = false;
/*  81 */       if ("cancel".equals(elemName))
/*  82 */         isCancel = true; else {
/*  83 */         if ((!"comp".equals(elemName)) && (!"except".equals(elemName))) {
/*     */           continue;
/*     */         }
/*     */       }
/*  87 */       RecurId recurId = null;
/*  88 */       Element recurIdElem = elem.getOptionalElement("exceptId");
/*  89 */       if (recurIdElem != null)
/*  90 */         recurId = CalendarUtils.parseRecurId(recurIdElem, tzmap);
/*  91 */       if (!isCancel) {
/*  92 */         ParsedDateTime dtStart = null;
/*  93 */         Element dtStartElem = elem.getElement("s");
/*  94 */         dtStart = CalendarUtils.parseDateTime(dtStartElem, tzmap);
/*  95 */         ParsedDateTime dtEnd = null;
/*  96 */         Element dtEndElem = elem.getOptionalElement("e");
/*  97 */         if (dtEndElem != null)
/*  98 */           dtEnd = CalendarUtils.parseDateTime(dtEndElem, tzmap);
/*  99 */         ParsedDuration dur = null;
/* 100 */         Element durElem = elem.getOptionalElement("dur");
/* 101 */         if (durElem != null)
/* 102 */           dur = ParsedDuration.parse(durElem);
/* 103 */         if ((dtEnd == null) && (dur == null)) {
/* 104 */           throw ServiceException.INVALID_REQUEST("Must specify either e or dur in " + elemName, null);
/*     */         }
/*     */         
/* 107 */         Element recurElem = elem.getOptionalElement("recur");
/* 108 */         if (recurElem != null)
/*     */         {
/* 110 */           recurrence = CalendarUtils.parseRecur(recurElem, tzmap, dtStart, dtEnd, dur, recurId);
/*     */         }
/*     */         else {
/* 113 */           if ((dur == null) && (dtStart != null) && (dtEnd != null))
/* 114 */             dur = dtEnd.difference(dtStart);
/* 115 */           if (recurId == null)
/* 116 */             recurId = new RecurId(dtStart, RecurId.RANGE_NONE);
/* 117 */           exceptions.add(new Recurrence.ExceptionRule(recurId, dtStart, dur, null));
/*     */         }
/* 119 */       } else if (recurId != null)
/*     */       {
/* 121 */         exceptions.add(new Recurrence.CancellationRule(recurId));
/*     */       }
/*     */     }
/*     */     
/* 125 */     ParsedRecurrence parsed = new ParsedRecurrence();
/* 126 */     if ((recurrence instanceof Recurrence.RecurrenceRule)) {
/* 127 */       Recurrence.RecurrenceRule rrule = (Recurrence.RecurrenceRule)recurrence;
/* 128 */       for (Recurrence.IException exception : exceptions) {
/* 129 */         rrule.addException(exception);
/*     */       }
/* 131 */       parsed.rrule = rrule;
/*     */     } else {
/* 133 */       parsed.exceptions = exceptions;
/*     */     }
/* 135 */     return parsed;
/*     */   }
/*     */   
/*     */   protected static List<CalendarItem.Instance> getInstances(ParsedRecurrence parsed, long rangeStart, long rangeEnd) throws ServiceException
/*     */   {
/* 140 */     List<CalendarItem.Instance> instances = null;
/* 141 */     if (parsed.rrule != null) {
/* 142 */       instances = parsed.rrule.expandInstances(0, rangeStart, rangeEnd);
/* 143 */     } else if ((parsed.exceptions != null) && (!parsed.exceptions.isEmpty())) {
/* 144 */       instances = new ArrayList(parsed.exceptions.size());
/* 145 */       for (Recurrence.IException except : parsed.exceptions)
/* 146 */         if (!(except instanceof Recurrence.CancellationRule))
/*     */         {
/* 148 */           ParsedDateTime dtStart = except.getStartTime();
/* 149 */           long invStart = dtStart != null ? dtStart.getUtcTime() : 0L;
/* 150 */           ParsedDateTime dtEnd = except.getEndTime();
/* 151 */           long invEnd = dtEnd != null ? dtEnd.getUtcTime() : 0L;
/* 152 */           if (((invStart < rangeEnd) && (invEnd > rangeStart)) || (dtStart == null)) {
/* 153 */             boolean allDay = false;
/* 154 */             int startTzo = 0;int endTzo = 0;
/* 155 */             if (dtStart != null) {
/* 156 */               allDay = !dtStart.hasTime();
/* 157 */               startTzo = dtStart.getOffset();
/*     */             }
/* 159 */             if (dtEnd != null)
/* 160 */               endTzo = dtEnd.getOffset();
/* 161 */             CalendarItem.Instance inst = new CalendarItem.Instance(0, null, dtStart != null, dtEnd != null, invStart, invEnd, allDay, startTzo, endTzo, true, false);
/*     */             
/*     */ 
/*     */ 
/* 165 */             instances.add(inst);
/*     */           }
/*     */         }
/*     */     }
/* 169 */     return instances;
/*     */   }
/*     */   
/*     */   protected static Element addInstance(Element parent, CalendarItem.Instance inst) throws ServiceException {
/* 173 */     Element instElem = parent.addElement("inst");
/* 174 */     if ((inst.hasStart()) && (inst.hasEnd())) {
/* 175 */       long instStart = inst.getStart();
/* 176 */       instElem.addAttribute("s", instStart);
/* 177 */       instElem.addAttribute("dur", inst.getEnd() - inst.getStart());
/* 178 */       if (inst.isAllDay()) {
/* 179 */         instElem.addAttribute("allDay", true);
/* 180 */         instElem.addAttribute("tzo", inst.getStartTzOffset());
/*     */       }
/* 182 */       instElem.addAttribute("ridZ", inst.getRecurIdZ());
/*     */     }
/* 184 */     return instElem;
/*     */   }
/*     */   
/*     */   protected static class ParsedRecurrence
/*     */   {
/*     */     public Recurrence.RecurrenceRule rrule;
/*     */     public List<Recurrence.IException> exceptions;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/ExpandRecur.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */